#include "../kernel.h"

struct initial_configuration_t initial_conf;

static int
uniprocessor_init(void)
{
	 initial_conf.has_pic = 1;
	 initial_conf.use_pic = 1;

	 initial_conf.ioapic_count = 0;
	 initial_conf.use_ioapic = 0;
	 initial_conf.lcpu_count = 1;
	 initial_conf.use_lapic = 0;
	 initial_conf.lapic_phys = 0;

	 apic_inv_map[0] = 0;
}

int
sys_init(void)
{
	 int err;
	 
	 /* Assume that we have pic */
	 initial_conf.has_pic = 1;

	 smbios_init();
	 
	 if ((err = acpi_init()) < 0)
	 {
		  kprintf("ACPI error, consider initialized as uniprocessor\n");
		  err = uniprocessor_init();
	 }
	 else if (initial_conf.lcpu_count == 0)
	 {
		  kprintf("No LCPU found, consider initialized as uniprocessor\n");
		  err = uniprocessor_init();
	 }
	 else
	 {
		  if (initial_conf.ioapic_count > 0)
		  	   initial_conf.use_ioapic = 1;
		  else initial_conf.use_pic = 1;
		  
		  initial_conf.use_lapic = 1;
	 }
	 
	 kprintf("PIC: %s, IOAPIC(%d): %s, LCPUs: %d, LAPIC: %s\n",
			 initial_conf.use_pic ? "enabled" : "disabled",
			 initial_conf.ioapic_count,
			 initial_conf.use_ioapic ? "enabled" : "disabled",
			 initial_conf.lcpu_count,
			 initial_conf.use_lapic ? "enabled" : "disabled");
	 return err;
}

int
sys_post_fix(void)
{
	 int i;
	 for (i = 0; i != IRQ_COUNT; ++ i)
	 {
		  int ap = ips_ap_alloc(0, 0);
		  set_irq_ap(i, ap);
		  sysconf.irq_ap[i] = ap;
	 }

	 int ret = pmem_page_alloc(RM_IMAGE_PAGES, &sysconf.rm_image_phys, 0, PPAGE_MANAGED);
	 if (ret < 0) return ret;
	 
	 for (i = 0; i != RM_IMAGE_PAGES; ++ i)
	 {
		  physaddr_t src = i << PAGE_SHIFT;
		  physaddr_t dst = sysconf.rm_image_phys + src;

		  char *dst_page;
		  BEGIN_TPAGE(dst, dst_page);

		  memmove(dst_page, KADDR(src), PAGE_SIZE);
		  
		  END_TPAGE;
	 }

	 return 0;
}
